<script>
import { dictMixin } from '@/mixin/dict'
import { parseSceneData } from '@/utils/scene-data'

export default {
  name: 'DeviceWarning',
  mixins: [dictMixin],
  props: {
    // 请求参数
    requestParams: {
      type: Object,
      default: () => ({})
    },
    // 弹窗数据
    popData: {
      type: Object,
      default: () => ({})
    },
    // 弹窗配置
    popConfig: {
      type: Object,
      default: () => ({})
    },
    // 弹窗取消
    close: {
      type: Boolean,
      default: false
    },
    // 弹窗确认
    confirm: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isAdd: true,
      formData: {},
      projectList: [],
      roomList: [],
      userList: [],
      deviceWarnList: [],
      thresholdLevelList: [],
      deviceList: []
    }
  },
  computed: {
    rules() {
      const rules = {
        warningName: [
          { required: true, message: '请输入预警名称' },
          { max: 50, message: '最长支持50个字符' }
        ],
        sceneProjectId: [
          { required: true, message: '请选择所属项目' }
        ],
        roomInfo: [
          { required: false, message: '请选择所属场景' }
        ],
        userIds: [
          { required: true, message: '请选择预警推送目标', validator: this.userValidator }
        ],
        thresholdLevel: [
          { required: true, message: '请选择预警级别' }
        ],
        dateRange: [
          { required: true, message: '请选择生效时间范围' }
        ]
      }
      for (let i = 0; i < this.deviceWarnList.length; i++) {
        rules['deviceId_' + i] = [{ required: true, message: '请选择关联设备' }]
        rules['modelId_' + i] = [{ required: true, message: '请选择设备参数' }]
        rules['thresholdValue_' + i] = [{ required: true, message: '请输入预警' }]
      }
      return rules
    }
  },
  watch: {
    popData: {
      async handler(data) {
        this.isAdd = !data.id
        if (!this.isAdd) {
          const detailRes = await this.$api.deviceWarning.detail(data.id)
          this.formData = detailRes.data
          this.formData.dateRange = [this.formData.startTime, this.formData.endTime]
          const roomInfo = []
          if (this.formData.sceneEdificeId) {
            roomInfo.push(this.formData.sceneEdificeId)
          }
          if (this.formData.sceneFloorId) {
            roomInfo.push(this.formData.sceneFloorId)
          }
          if (this.formData.sceneRoomId) {
            roomInfo.push(this.formData.sceneRoomId)
          }
          this.formData.roomInfo = roomInfo
          await this.roomInfoChangeHandler(this.formData.roomInfo)
          this.formData.userIds = detailRes.data.warningUsers.map(item => item.id)
          this.deviceWarnList = detailRes.data.warningThresholds
          for (let i = 0; i < detailRes.data.warningThresholds.length; i++) { // 先设置值
            const item = detailRes.data.warningThresholds[i]
            this.formData['deviceId_' + i] = item.deviceId
            this.formData['modelId_' + i] = item.modelId
            this.formData['thresholdValue_' + i] = item.thresholdValue
          }
          for (let i = 0; i < detailRes.data.warningThresholds.length; i++) { // 再触发下拉选项数据并校验规则
            const item = detailRes.data.warningThresholds[i]
            this.formData['thresholdValue_' + i] = item.thresholdValue
            await this.deviceWarnChangeHandler(item.deviceId, i)
            this.deviceWarnModelChangeHandler(item.modelId, i)
          }
          this.projectChangeHandler(this.formData.sceneProjectId)
        } else {
          this.formData = data
        }
        if (this.deviceWarnList.length === 0) {
          this.deviceWarnList.push({})
        }
      },
      deep: true,
      immediate: true
    },
    confirm() {
      const params = {
        ...(this.formData || {})
      }
      this.submit(params)
    }
  },
  created() {
    this.loadingInitData()
  },
  methods: {
    userValidator(rule, value, callback) {
      if (this.formData.userIds != null && this.formData.userIds.length > 0) {
        return callback()
      }
      return callback()
    },
    addDeviceWarning() {
      this.deviceWarnList.push({})
    },
    async deviceWarnChangeHandler(value, index) {
      const res = await this.$api.device.modelList(value)
      const val = Object.assign({}, this.deviceWarnList[index])
      val.deviceId = value
      val.modelList = res.data.filter(item => item.fieldType !== '6' && item.fieldType !== '7') // 不展示数组和对象
      this.$set(this.deviceWarnList, index, val)
    },
    deviceWarnModelChangeHandler(value, index) {
      const deviceWarnItem = this.deviceWarnList[index]
      deviceWarnItem.modelId = value
      if (this.isAdd) {
        delete deviceWarnItem.thresholdValue
      }
      const model = deviceWarnItem.modelList.find(item => item.id === value)
      const judgeRuleList = []
      let thresholdList = []
      let thresholdElType = ''
      switch (model.fieldType) {
        case '1': // 整数
        case '2': // 小数
          deviceWarnItem.judgeRule = deviceWarnItem.judgeRule || '1' //默认值为1
          this.formData[`judgeRule_${index}`] = deviceWarnItem.judgeRule
          judgeRuleList.push({ value: '1', label: '大于等于' })
          judgeRuleList.push({ value: '2', label: '小于等于' })
          thresholdElType = 'input-number'
          break
        case '3': // 布尔
          delete deviceWarnItem.judgeRule
          delete this.formData[`judgeRule_${index}`]
          thresholdElType = 'select'
          thresholdList.push({
            value: model.dataExtMap.trueValue,
            label: model.dataExtMap.trueValue
          })
          thresholdList.push({
            value: model.dataExtMap.falseValue,
            label: model.dataExtMap.falseValue
          })
          break
        case '4': // 枚举
          delete deviceWarnItem.judgeRule
          delete this.formData[`judgeRule_${index}`]
          thresholdElType = 'select'
          thresholdList = model.dataExtMap.enumList
          break
        case '5':// 字符串
          delete deviceWarnItem.judgeRule
          delete this.formData[`judgeRule_${index}`]
          thresholdElType = 'input'
          break
      }
      deviceWarnItem.judgeRuleList = judgeRuleList
      deviceWarnItem.thresholdElType = thresholdElType
      deviceWarnItem.thresholdList = thresholdList
      this.$set(this.deviceWarnList, index, deviceWarnItem)
    },
    async roomInfoChangeHandler(value) {
      const param = {
        sceneProjectId: this.formData.sceneProjectId
      }
      if (value != null && value.length !== 0) {
        param.sceneEdificeId = value[0]
        param.sceneFloorId = value.length > 1 ? value[1] : null
        param.sceneRoomId = value.length > 2 ? value[2] : null
      }
      const deviceRes = await this.$api.commonSelected({
        code: 'DeviceSelected',
        param: JSON.stringify(param)
      })
      this.deviceList = deviceRes.data
    },
    projectChangeHandler(value) {
      if (value == null || value === '') {
        this.roomList = []
      } else {
        this.$api.sceneRoom.queryRoomList({
          sceneProjectId: value,
          sortColumn: 'floorName',
          sortOrder: 'asc'
        }).then(response => {
          this.roomList = parseSceneData(response.data)
        })
        this.roomInfoChangeHandler(null)
      }
    },
    async loadingInitData() {
      this.$api.commonSelected({
        code: 'SceneProjectSelected'
      }).then(response => {
        this.projectList = response.data
      })
      this.$api.commonSelected({
        code: 'UserSelected'
      }).then(response => {
        this.userList = response.data
      })
      this.$api.dictList({
        codeList: ['ecp-admin.earlyWarningRecord.thresholdLevel']
      }).then(response => {
        this.thresholdLevelList = response.data['ecp-admin.earlyWarningRecord.thresholdLevel']
      })
    },
    /**
     * change事件
     */
    handlerSelectData(config) {
      const Ref = this.$refs[config.prop]
      if (Ref && config.isClosePop) {
        Ref.dropDownVisible = false
      }
    },
    judgeRuleChangeHandler(value, item, index) {
      item.judgeRule = value
      this.formData[`judgeRule_${index}`] = value
      this.$forceUpdate()
    },
    thresholdValueChangeHandler(value, item) {
      item.thresholdValue = value
      this.$forceUpdate()
    },
    /**
     * 提交
     */
    submit(params) {
      delete params.createTm
      delete params.modifyTm
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          if (this.deviceWarnList.length === 0) {
            this.$message.error('请选择设备预警')
            return
          }
          if (params.dateRange.length > 0) {
            params.startTime = params.dateRange[0]
            params.endTime = params.dateRange[1]
          }
          params.sceneEdificeId = params.roomInfo[0]
          params.sceneFloorId = params.roomInfo.length > 0 ? params.roomInfo[1] : null
          params.sceneRoomId = params.roomInfo.length > 1 ? params.roomInfo[2] : null
          const warnList = this.deviceWarnList.map(item => {
            return {
              deviceId: item.deviceId,
              modelId: item.modelId,
              judgeRule: item.judgeRule || '',
              thresholdValue: item.thresholdValue
            }
          })
          params.warningJson = JSON.stringify(warnList)
          const res = await this.$api.deviceWarning[
            this.isAdd ? 'add' : 'update'
            ](params)
          if (Number(res.code) === 1000) {
            this.$message.success(`${this.isAdd ? '新增' : '编辑'}成功！`)
            this.$emit('onFinish', 'device-warning-add')
          }
        }
      })
    }
  }
}
</script>

<template>
  <div class="device-warning-box">
    <el-form ref="form" :model="formData" :rules="rules" label-width="110px" label-position="left">
      <el-form-item label="预警名称" prop="warningName">
        <el-input v-model="formData.warningName"></el-input>
      </el-form-item>
      <el-form-item label="所属项目" prop="sceneProjectId">
        <el-select v-model="formData.sceneProjectId" @change="projectChangeHandler" clearable>
          <el-option v-for="item in projectList" :key="item.id" :value="item.value" :label="item.label"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="所属场景" prop="roomInfo">
        <el-cascader v-model="formData.roomInfo" :options="roomList" placeholder="请选择" clearable
                     @change="roomInfoChangeHandler"
                     :props="{ checkStrictly: true }" />
      </el-form-item>
      <el-form-item label="设备预警"
                    style="border: 1px solid #dcdcdc;border-radius: 4px; padding-bottom: 10px;padding-left: 4px">
        <div style="text-align: right;margin-right: 20px">
          <el-button @click="addDeviceWarning" type="text" :disabled="deviceWarnList.length >= 10">添加一行</el-button>
        </div>
        <div style="margin-left: -110px">
          <el-row v-for="(item,index) in deviceWarnList" :key="`device_warn_${index}`" style="margin-bottom: 12px">
            <el-col :span="7">
              <el-form-item label="关联设备" required label-width="80px" :prop="`deviceId_${index}`">
                <el-select v-model="formData[`deviceId_${index}`]"
                           @change="(value) => deviceWarnChangeHandler(value,index)">
                  <el-option v-for="item in deviceList" :key="item.id" :value="item.value"
                             :label="item.label"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="7">
              <el-form-item label="设备参数" required label-width="80px" :prop="`modelId_${index}`">
                <el-select v-model="formData[`modelId_${index}`]"
                           @change="value => deviceWarnModelChangeHandler(value,index)">
                  <el-option v-for="modelItem in item.modelList" :key="modelItem.id" :value="modelItem.id"
                             :label="modelItem.modelName"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="预警" required label-width="50px" :prop="`thresholdValue_${index}`">
                <div style="display: flex">
                  <el-select v-if="item.judgeRuleList != null && item.judgeRuleList.length > 0"
                             v-model="formData[`judgeRule_${index}`]"
                             @change="value =>  judgeRuleChangeHandler(value,item,index)">
                    <el-option v-for="judgeRule in item.judgeRuleList" :key="judgeRule.value"
                               :value="judgeRule.value" :label="judgeRule.label"></el-option>
                  </el-select>

                  <el-input v-if="item.thresholdElType === 'input'" v-model="formData[`thresholdValue_${index}`]"
                            @change="(value) => item.thresholdValue = value" />
                  <el-input-number v-else-if="item.thresholdElType === 'input-number'"
                                   @change="(value) => thresholdValueChangeHandler(value,item)" :step="1"
                                   v-model="formData[`thresholdValue_${index}`]" size="small"
                                   style="width: 100%" />
                  <el-select v-else v-model="formData[`thresholdValue_${index}`]"
                             @change="(value) => item.thresholdValue = value">
                    <el-option v-for="thresholdItem in item.thresholdList" :key="thresholdItem.value"
                               :value="thresholdItem.value" :label="thresholdItem.label"
                    ></el-option>
                  </el-select>
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="2" style="padding-left: 4px">
              <el-button v-if="deviceWarnList.length > 1" type="danger" icon="el-icon-delete" size="mini"
                         @click="() => {
                           deviceWarnList.splice(index, 1)
                           delete formData[`deviceId_${index}`]
                           delete formData[`modelId_${index}`]
                           delete formData[`judgeRule_${index}`]
                           delete formData[`thresholdValue_${index}`]
                         }" />
            </el-col>
          </el-row>
        </div>
      </el-form-item>
      <el-form-item label="预警推送目标" prop="userIds">
        <el-select v-model="formData.userIds" @change="() => this.$forceUpdate()" placeholder="请选择" multiple
                   style="width: 100%">
          <el-option v-for="item in userList" :key="item.value" :value="item.value" :label="item.label"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="预警级别" prop="thresholdLevel">
        <el-select v-model="formData.thresholdLevel" placeholder="请选择预警级别" style="width: 100%">
          <el-option v-for="item in thresholdLevelList" :key="item.value" :value="item.value"
                     :label="item.label"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="生效时间范围" prop="dateRange">
        <el-date-picker v-model="formData.dateRange" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
                        type="datetimerange"
                        range-separator="至" />
      </el-form-item>
    </el-form>
  </div>
</template>
